//
// Created by 郝羽 on 2018/6/11.
//

#include <glib-2.0/glib.h>

#include <thread>
#include <list>

struct worker {
    int64_t next_timeout;
};

gboolean worker_timeout(gpointer data) {
    auto w = static_cast<worker*>(data);
    int64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch()).count();
    int64_t drift = now - w->next_timeout;

    printf("worker: %p drift: %dms\n", w, drift);

    w->next_timeout = now + 10;

    std::this_thread::sleep_for(std::chrono::milliseconds(10+drift));

    return G_SOURCE_CONTINUE;
}

void worker_thread() {
    auto ctx = g_main_context_new();

    g_main_context_push_thread_default(ctx);

    auto worker_timer = g_timeout_source_new(10);

    auto w = new worker();

    w->next_timeout = std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch()).count();

    g_source_set_callback(worker_timer, worker_timeout, w, nullptr);

    g_source_attach(worker_timer, ctx);

    auto loop = g_main_loop_new(ctx, TRUE);

    g_main_loop_run(loop);

};

int main() {


    std::thread w1(worker_thread);
    std::thread w2(worker_thread);
    std::thread w3(worker_thread);
    std::thread w4(worker_thread);

    w1.join();
    w2.join();
    w3.join();
    w4.join();


}